package com.itheima.lamabd1why;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: Ethan Yankang
 * @Program: JAVA核心技术
 * @Date: 2024-08-10 13:24
 **/
public class TestMain {
    List<Employee> employees = Arrays.asList(
            new Employee("张三", 18, 9999.99),
            new Employee("李四", 38, 5555.55),
            new Employee("王五", 60, 6666.66),
            new Employee("赵六", 16, 7777.77),
            new Employee("田七", 18, 3333.33)
    );
//    ===================================Collection==========================================================
//    常规集合方法遍历
    /*
     * @description 找到年龄大于30岁的员工
     * @params
     * @return
     */

    public List<Employee> filterEmployeesByAge(List<Employee> list) {
        List<Employee> employees = new ArrayList<>();
        for (Employee e : list) {
            if (e.getAge() >= 30) {
                employees.add(e);
            }
        }
        return employees;
    }

    @Test
    public void testByCollectionAgeGreaterThan30() {
        List<Employee> employeeList = filterEmployeesByAge(this.employees);
        for (Employee e : employeeList) {
            System.out.println(e);
        }
    }

    /*
     * @description 找到员工工资大于或者等于5000的员工信息。
     * @params
     * @return
     */
    public List<Employee> filterEmployeesBySalary(List<Employee> list) {
        List<Employee> employees = new ArrayList<>();
        for (Employee e : list) {
            if (e.getSalary() >= 5000) {
                employees.add(e);
            }
        }
        return employees;
    }

    @Test
    public void testByCollectionSalaryGreaterThan5000() {
        List<Employee> employeeList = filterEmployeesBySalary(this.employees);
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }
    }



    /*
     * @description 设计模式遍历
     * @params
     * @return
     */

//    ===================================DesignPattern==========================================================

//可以看到，这样的常规方法很麻烦，而且对比filterEmployeesByAge()方法和filterEmployeesBySalary方法后，
// 我们发现，大部分的方法体是相同的，只是for循环中对于条件的判断不同。那么有没有其他方法呢？
//下面介绍设计模式方法,将公共模块提取出来，将不同的模块分别实现。(策略模式)


    //优化方式一，传入谓语逻辑，提取公共代码
    public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> myPredicate) {
        List<Employee> employees = new ArrayList<>();
        for (Employee e : list) {
            if (myPredicate.filter(e)) {
                employees.add(e);
            }
        }
        return employees;
    }


    //    测试age>30的员工
    @Test
    public void testByDesignPatternAgeGreaterThan30() {
        List<Employee> employeeList = this.filterEmployee(this.employees, new FilterEmployeeByAge());
        for (Employee e : employeeList) {
            System.out.println(e);
        }
    }

    //    测试salary>5000的员工
    @Test
    public void testByDesignPatternSalaryGreaterThan5000() {
        List<Employee> employeeList = this.filterEmployee(this.employees, new FilterEmployeeBySalary());
        for (Employee e : employeeList) {
            System.out.println(e);
        }
    }


    /*
     * @description 匿名内部类遍历
     * @params
     * @return
     */


    //    ===================================匿名内部类==========================================================
    @Test
    public void testByAnonymousInnerClassGreaterThan30() {
        List<Employee> employeeList = this.filterEmployee(this.employees, new MyPredicate<Employee>() {
            @Override
            public boolean filter(Employee employee) {
                return employee.getAge() >= 30;
            }
        });
        for (Employee e : employeeList) {
            System.out.println(e);
        }
    }


    /*
     * @description lamabd+Str
     * @params
     * @return
     */

    //    ===================================lamabd+Stream==========================================================
//    设计模式优化后还是存在问题，每次定义一个过滤策略的时候，我们都要单独创建一个过滤类！！,这很麻烦。
//    而上面的匿名内部类虽然简化了很多，但是还是没有那种惊为天人的感觉。又没有更好的实现方法？？？
//    下面讲解lamabd表达式，真正的王者
//    使用Lambda表达式结合Stream API，只要给出相应的集合，我们就可以完成对集合的各种过滤并输出结果信息。
    @Test
    public void testByLamabdGreaterThan30AndSalaryGreaterThan5000() {
        System.out.println("年龄大于30的");
        filterEmployee(this.employees, (e) -> e.getAge() >= 30).forEach(System.out::println);
        System.out.println("\n薪资大于5000的");
        filterEmployee(this.employees, (e) -> e.getSalary() >= 5000).forEach(System.out::println);
        System.out.println("\n使用stream+lamabd提取薪资大于5000的前两个人");
        this.employees.stream().filter((e) -> e.getSalary() >= 5000).limit(2).forEach(System.out::println);
        System.out.println("\n使用stream+lamabd提取薪资大于5000的前两个人的姓名");
        this.employees.stream().filter((e) -> e.getSalary() >= 5000).limit(2).map(Employee::getName).forEach(System.out::println);
    }
}

//    @Test
//public void test12(){
//    employees.stream().filter((e) -> e.getSalary() >= 5000).map(Employee::getName).forEach(System.out::println);
//}
//}
//    看到没，使用Lambda表达式只需要一行代码就完成了员工信息的过滤和输出。是不是很6呢。太666666666666了。
